csspathnode: Handle context going away
authorBenjamin Otte <otte@redhat.com>
Wed, 18 Mar 2015 17:22:17 +0000 (18:22 +0100)
committerBenjamin Otte <otte@redhat.com>
Wed, 18 Mar 2015 17:24:45 +0000 (18:24 +0100)
Sometimes path nodes can survive longer than the style context that
created them. Don't crash in those cases.

Fixes startup of mutter.

Testcase included.

https://bugzilla.gnome.org/show_bug.cgi?id=746407

gtk/gtkcsspathnode.c
gtk/gtkcsspathnodeprivate.h
gtk/gtkstylecontext.c
testsuite/gtk/stylecontext.c

index e9b5298733f88cb3e138e6f9d1b789db2059acaa..fecb4552a91b3e28bb0829452a4ace64e3501067 100644 (file)
@@ -156,6 +156,17 @@ gtk_css_path_node_new (GtkStyleContext *context)
   return GTK_CSS_NODE (node);
 }
 
+void
+gtk_css_path_node_unset_context (GtkCssPathNode *node)
+{
+  gtk_internal_return_if_fail (GTK_IS_CSS_PATH_NODE (node));
+  gtk_internal_return_if_fail (node->context != NULL);
+
+  node->context = NULL;
+
+  gtk_css_node_invalidate_style_provider (GTK_CSS_NODE (node));
+}
+
 void
 gtk_css_path_node_set_widget_path (GtkCssPathNode *node,
                                    GtkWidgetPath  *path)
index dd3831cc5bbceb65ff22c9f3803d9012cde2c773..4c7d60e5bda1a0efa08cd2c841526848928f2f90 100644 (file)
@@ -50,6 +50,8 @@ GType                   gtk_css_path_node_get_type         (void) G_GNUC_CONST;
 
 GtkCssNode *            gtk_css_path_node_new              (GtkStyleContext *context);
 
+void                    gtk_css_path_node_unset_context    (GtkCssPathNode *node);
+
 void                    gtk_css_path_node_set_widget_path  (GtkCssPathNode *node,
                                                             GtkWidgetPath  *path);
 GtkWidgetPath *         gtk_css_path_node_get_widget_path  (GtkCssPathNode *node);
index bbf629a39c243685a62852b2c4b1d5bb290922cb..3786e356d5f59e3019a148f497f12892bd52ed93 100644 (file)
@@ -365,12 +365,15 @@ gtk_style_context_finalize (GObject *object)
   style_context = GTK_STYLE_CONTEXT (object);
   priv = style_context->priv;
 
+  while (priv->saved_nodes)
+    gtk_style_context_pop_style_node (style_context);
+  if (GTK_IS_CSS_PATH_NODE (priv->cssnode))
+    gtk_css_path_node_unset_context (GTK_CSS_PATH_NODE (priv->cssnode));
+
   gtk_style_context_clear_parent (style_context);
 
   gtk_style_context_set_cascade (style_context, NULL);
 
-  while (priv->saved_nodes)
-    gtk_style_context_pop_style_node (style_context);
   g_object_unref (priv->cssnode);
 
   gtk_style_context_clear_property_cache (style_context);
index fcbc0a16121341061958f795f161e06c8500f762..4d6438cb33c9f278817e1544333c5aac4511427a 100644 (file)
@@ -352,6 +352,20 @@ test_set_widget_path_saved (void)
   g_object_unref (context);
 }
 
+void
+test_widget_path_parent (void)
+{
+  GtkStyleContext *parent, *context;
+
+  parent = gtk_style_context_new ();
+  context = gtk_style_context_new ();
+
+  gtk_style_context_set_parent (context, parent);
+
+  g_object_unref (parent);
+  g_object_unref (context);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -364,6 +378,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/style/basic", test_basic_properties);
   g_test_add_func ("/style/invalidate-saved", test_invalidate_saved);
   g_test_add_func ("/style/set-widget-path-saved", test_set_widget_path_saved);
+  g_test_add_func ("/style/widget-path-parent", test_widget_path_parent);
 
   return g_test_run ();
 }